package com.huang;

import com.huang.aop.AopConfig;
import com.huang.aop.MyCalculate;
import com.huang.config.HelloConfig;
import com.huang.entity.User;
import com.huang.service.HelloService;
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.aop.framework.AdvisedSupport;
import org.springframework.aop.framework.DefaultAdvisorChainFactory;
import org.springframework.aop.framework.DefaultAopProxyFactory;
import org.springframework.aop.framework.ReflectiveMethodInvocation;
import org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.SingletonBeanRegistry;
import org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration;
import org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.interceptor.TransactionInterceptor;
import org.springframework.transaction.support.AbstractPlatformTransactionManager;
import org.springframework.transaction.support.TransactionSynchronizationManager;


/**
 * <pre>
 * 【Spring源码阅读】
 * 一、IOC：
 * @see AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(Class[])
 *   @see AbstractApplicationContext#refresh()
 * 		@see AbstractBeanFactory#doGetBean
 * 		   @see AbstractBeanFactory#getSingleton(String, ObjectFactory)
 * 		      @see AbstractAutowireCapableBeanFactory#doCreateBean
 * 		         @see AbstractAutowireCapableBeanFactory#populateBean
 *
 * 二、AOP：
 * 1、生成代理对象
 * @see AbstractAutoProxyCreator#postProcessAfterInitialization(Object, String)
 *     @see AnnotationAwareAspectJAutoProxyCreator
 *         @see AbstractAutoProxyCreator#wrapIfNecessary
 *            @see AnnotationAwareAspectJAutoProxyCreator#findAdvisorsThatCanApply
 *                @see AbstractAutoProxyCreator#createProxy
 *                     @see DefaultAopProxyFactory#createAopProxy
 *                      1)实现了接口、targetClass本身是接口：
 *                         走JDK代理： {@link org.springframework.aop.framework.JdkDynamicAopProxy}
 *                      2)没实现接口、指定了proxyTargetClass=true：
 *                         走Cglib代理： {@link org.springframework.aop.framework.CglibAopProxy}
 *                              @see org.springframework.aop.framework.CglibAopProxy#getCallbacks
 * 2、执行：以cglib代理为例 (博客：https://blog.csdn.net/u013277209/article/details/114739792)
 * @see org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor#intercept
 *    @see DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice
 *       @see org.springframework.aop.framework.CglibAopProxy.CglibMethodInvocation#proceed()
 *           @see ReflectiveMethodInvocation#proceed()
 * 三、事务
 *
 * 1、注解驱动事务配置
 * @see EnableTransactionManagement
 *     @see ProxyTransactionManagementConfiguration
 *
 * 2、切面
 * @see BeanFactoryTransactionAttributeSourceAdvisor
 *
 * 3、调用代理对象：
 * @see TransactionInterceptor#invoke
 *     @see TransactionAspectSupport#invokeWithinTransaction
 *     		@see TransactionAspectSupport#createTransactionIfNecessary
 *     			 @see AbstractPlatformTransactionManager#getTransaction
 * @see TransactionSynchronizationManager：里面一堆ThreadLocal
 * </pre>
 */
public class MainApplication {

	public static void main(String[] args) {
		// 将配置类注册到容器中
		// 让他去扫描bean
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AopConfig.class);
		// 去容器中取出bean
		MyCalculate bean = applicationContext.getBean(MyCalculate.class);
		System.out.println(bean.add(1, 2));

		MyCalculate bean2 = applicationContext.getBean("myCalculate", MyCalculate.class);
		System.out.println(bean2.add(1, 2));


		// 为了导包，没有实际意义
		importClass();
	}
	/**
	 * 导包
	 */
	private static void importClass() {
		AbstractPlatformTransactionManager abstractPlatformTransactionManager;
		PlatformTransactionManager platformTransactionManager;
		ProxyTransactionManagementConfiguration proxyTransactionManagementConfiguration;
		TransactionInterceptor transactionInterceptor;
		TransactionAspectSupport transactionAspectSupport;
		BeanFactoryTransactionAttributeSourceAdvisor beanFactoryTransactionAttributeSourceAdvisor;
		EnableTransactionManagement enableTransactionManagement;
		ReflectiveMethodInvocation reflectiveMethodInvocation;
		DefaultAdvisorChainFactory defaultAdvisorChainFactory;
		AbstractApplicationContext applicationContext = null;
		ConfigurableBeanFactory configurableBeanFactory = null;
		SingletonBeanRegistry singletonBeanRegistry = null;
		AbstractBeanFactory abstractBeanFactory = null;
		SmartInitializingSingleton smartInitializingSingleton = null;
		AbstractAutowireCapableBeanFactory abstractAutowireCapableBeanFactory = null;
		ListableBeanFactory listableBeanFactory = null;
		AbstractAutoProxyCreator abstractAutoProxyCreator;
		AnnotationAwareAspectJAutoProxyCreator annotationAwareAspectJAutoProxyCreator;
		DefaultAopProxyFactory defaultAopProxyFactory;
	}
}
